# -*- coding: utf-8 -*-
"""
用户认证控制器
"""
from flask import Blueprint, request
from app.services.auth_service import AuthService
from app.config.database import SessionLocal
from app.utils.auth import token_required, get_current_user
from app.utils.response import (
    success_response, bad_request_response, login_failed_response,
    internal_error_response, unauthorized_response
)

auth_bp = Blueprint('auth', __name__, url_prefix='/api/auth')

@auth_bp.route('/login', methods=['POST'])
def login():
    """
    用户登录API

    Request Body:
    {
        "username": "用户名或邮箱",
        "password": "密码"
    }

    Response:
    {
        "code": 200,
        "message": "登录成功",
        "data": {
            "access_token": "访问令牌",
            "token_type": "bearer",
            "user": {用户信息}
        }
    }
    """
    try:
        data = request.get_json()
        print(f"data: {data}")

        if not data:
            return bad_request_response("请求数据格式错误")

        username = data.get('username')
        password = data.get('password')

        if not username or not password:
            return bad_request_response("用户名和密码不能为空")

        # 创建数据库会话
        db = SessionLocal()

        try:
            # 调用登录服务，返回Result对象
            result = AuthService.login(db, username, password)

            # 直接返回Result对象的响应，HTTP状态码由Result决定
            return result.to_response()

        finally:
            db.close()

    except Exception as e:
        return internal_error_response(f"登录失败：{str(e)}")

@auth_bp.route('/profile', methods=['GET'])
@token_required
def get_profile():
    """
    获取当前用户信息

    Headers:
    Authorization: Bearer <token>

    Response:
    {
        "code": 200,
        "message": "获取成功",
        "data": {用户信息}
    }
    """
    try:
        current_user = get_current_user()
        return success_response(current_user.to_dict(), "获取用户信息成功")

    except Exception as e:
        return internal_error_response(f"获取用户信息失败：{str(e)}")

@auth_bp.route('/logout', methods=['POST'])
@token_required
def logout():
    """
    用户登出

    Headers:
    Authorization: Bearer <token>

    Response:
    {
        "code": 200,
        "message": "登出成功"
    }
    """
    # 在实际应用中，这里可以将token加入黑名单
    # 目前只是返回成功响应
    return success_response(message="登出成功")

@auth_bp.route('/register', methods=['POST'])
def register():
    """
    用户注册API
    目的：允许新用户创建账号并自动登录
    功能：验证注册信息、创建用户、返回访问令牌

    Request Body:
    {
        "username": "用户名（必填，3-50字符，唯一）",
        "email": "邮箱地址（必填，唯一）",
        "password": "密码（必填，6-20字符）",
        "nickname": "昵称（可选，不填则默认为用户名）",
        "phone": "手机号码（可选）"
    }

    Response (成功):
    {
        "code": 200,
        "message": "注册成功",
        "data": {
            "access_token": "访问令牌",
            "token_type": "bearer",
            "user": {
                "id": 1,
                "username": "用户名",
                "email": "邮箱",
                "nickname": "昵称",
                ...
            }
        }
    }

    Response (失败):
    {
        "code": 400/1005,
        "message": "错误信息（如：用户名已存在、邮箱已被注册等）"
    }
    """
    try:
        # 获取请求体JSON数据
        data = request.get_json()

        # 验证请求数据格式是否正确
        if not data:
            return bad_request_response("请求数据格式错误")

        # 提取必填字段：用户名、邮箱、密码
        username = data.get('username')
        email = data.get('email')
        password = data.get('password')

        # 提取可选字段：昵称、手机号
        nickname = data.get('nickname')
        phone = data.get('phone')

        # 验证必填字段不能为空
        if not username or not email or not password:
            return bad_request_response("用户名、邮箱和密码不能为空")

        # 验证用户名长度（3-50字符）
        if len(username) < 3 or len(username) > 50:
            return bad_request_response("用户名长度必须在3-50个字符之间")

        # 验证密码长度（6-20字符）
        if len(password) < 6 or len(password) > 20:
            return bad_request_response("密码长度必须在6-20个字符之间")

        # 简单验证邮箱格式（包含@符号）
        if '@' not in email or '.' not in email:
            return bad_request_response("邮箱格式不正确")

        # 验证邮箱长度不超过100字符（数据库字段限制）
        if len(email) > 100:
            return bad_request_response("邮箱长度不能超过100个字符")

        # 如果提供了昵称，验证长度不超过100字符
        if nickname and len(nickname) > 100:
            return bad_request_response("昵称长度不能超过100个字符")

        # 如果提供了手机号，验证长度不超过20字符
        if phone and len(phone) > 20:
            return bad_request_response("手机号长度不能超过20个字符")

        # 创建数据库会话对象
        db = SessionLocal()

        try:
            # 调用注册服务，返回Result对象
            result = AuthService.register(
                db=db,
                username=username,
                email=email,
                password=password,
                nickname=nickname,
                phone=phone
            )

            # 将Result对象转换为Flask响应，HTTP状态码由Result决定
            return result.to_response()

        finally:
            # 确保数据库会话被关闭，释放连接资源
            db.close()

    except Exception as e:
        # 捕获所有异常，返回服务器内部错误响应
        return internal_error_response(f"注册失败：{str(e)}")

@auth_bp.route('/profile', methods=['PUT'])
@token_required
def update_profile():
    """
    更新用户资料API
    目的：允许用户修改个人信息
    功能：更新昵称、个人简介、手机号等信息（不包括邮箱和用户名）

    Headers:
    Authorization: Bearer <token>

    Request Body (所有字段均为可选，支持部分更新):
    {
        "nickname": "新昵称（可选，最多100字符）",
        "bio": "个人简介（可选，文本类型）",
        "phone": "手机号码（可选，最多20字符）",
        "avatar": "头像文件路径（可选，由头像上传接口返回，最多255字符）"
    }

    Response (成功):
    {
        "code": 200,
        "message": "更新资料成功",
        "data": {
            "id": 1,
            "username": "testuser",
            "email": "test@example.com",
            "nickname": "新昵称",
            "bio": "个人简介",
            "phone": "13800138000",
            "avatar": "http://...",
            "status": 1,
            "created_at": "2024-01-01T00:00:00",
            "updated_at": "2024-01-20T10:30:00"
        }
    }

    Response (失败):
    {
        "code": 400/404/500,
        "message": "错误信息"
    }
    """
    try:
        # 获取当前登录用户
        current_user = get_current_user()
        if not current_user:
            return unauthorized_response("用户认证失败")

        # 提取用户ID
        user_id = current_user.id

        # 获取请求体JSON数据
        data = request.get_json()

        # 验证请求数据格式是否正确
        if not data:
            return bad_request_response("请求数据格式错误")

        # 提取可选字段：昵称、个人简介、手机号、头像路径
        nickname = data.get('nickname')
        bio = data.get('bio')
        phone = data.get('phone')
        avatar = data.get('avatar')

        # 创建数据库会话对象
        db = SessionLocal()

        try:
            # 调用更新资料服务，返回Result对象
            result = AuthService.update_profile(
                db=db,
                user_id=user_id,
                nickname=nickname,
                bio=bio,
                phone=phone,
                avatar=avatar
            )

            # 将Result对象转换为Flask响应
            return result.to_response()

        finally:
            # 确保数据库会话被关闭，释放连接资源
            db.close()

    except Exception as e:
        # 捕获所有异常，返回服务器内部错误响应
        return internal_error_response(f"更新资料失败：{str(e)}")

@auth_bp.route('/password', methods=['PUT'])
@token_required
def change_password():
    """
    修改密码API
    目的：允许用户修改登录密码
    功能：验证旧密码后更新为新密码

    Headers:
    Authorization: Bearer <token>

    Request Body:
    {
        "old_password": "旧密码（必填）",
        "new_password": "新密码（必填，6-20字符）"
    }

    Response (成功):
    {
        "code": 200,
        "message": "修改密码成功"
    }

    Response (失败):
    {
        "code": 400/404/500,
        "message": "错误信息（如：旧密码错误、新密码不符合要求等）"
    }
    """
    try:
        # 获取当前登录用户
        current_user = get_current_user()
        if not current_user:
            return unauthorized_response("用户认证失败")

        # 提取用户ID
        user_id = current_user.id

        # 获取请求体JSON数据
        data = request.get_json()

        # 验证请求数据格式是否正确
        if not data:
            return bad_request_response("请求数据格式错误")

        # 提取必填字段：旧密码、新密码
        old_password = data.get('old_password')
        new_password = data.get('new_password')

        # 验证必填字段不能为空
        if not old_password or not new_password:
            return bad_request_response("旧密码和新密码不能为空")

        # 创建数据库会话对象
        db = SessionLocal()

        try:
            # 调用修改密码服务，返回Result对象
            result = AuthService.change_password(
                db=db,
                user_id=user_id,
                old_password=old_password,
                new_password=new_password
            )

            # 将Result对象转换为Flask响应
            return result.to_response()

        finally:
            # 确保数据库会话被关闭，释放连接资源
            db.close()

    except Exception as e:
        # 捕获所有异常，返回服务器内部错误响应
        return internal_error_response(f"修改密码失败：{str(e)}")